package com.zbkj.service.util;

import com.zbkj.common.constants.IntegralDetailConstants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.Integral.IntegralParameter;
import com.zbkj.common.model.order.StoreOrder;
import com.zbkj.common.model.order.StoreOrderInfo;
import com.zbkj.common.model.system.SystemUserLevel;
import com.zbkj.common.model.user.UserIntegral;
import com.zbkj.common.model.user.UserIntegralDetail;
import com.zbkj.common.response.StoreProductResponse;
import com.zbkj.common.utils.DateUtil;

import com.zbkj.service.service.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 一号通工具类
 * +----------------------------------------------------------------------
 * | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
 * +----------------------------------------------------------------------
 * | Author: CRMEB Team <admin@crmeb.com>
 * +----------------------------------------------------------------------
 */
@Component
public class IntegralUtil {

    @Autowired
    private IntegralParameterService integralParameterService;

    @Autowired
    private SystemUserLevelService systemUserLevelService;

    @Autowired
    private UserIntegralDetailService userIntegralDetailService;  //用户积分明细

    @Autowired
    private OrderPayService orderPayService;



    // 获取积分参数配置， id为方案1
    //    IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);

    /*
     * 通过积分类型获取积分的值
     **/
    public BigDecimal getIntegralByType(UserIntegral userIntegral, String integralType) {
        switch (integralType) {
            case IntegralDetailConstants.INTEGRAL_TYPE_VALUE_ADD:
                return userIntegral.getValueAddIntegral();
            case IntegralDetailConstants.INTEGRAL_TYPE_GREEN:
                return userIntegral.getGreenIntegral();
            case IntegralDetailConstants.INTEGRAL_TYPE_CONTRIBUTION:
                return userIntegral.getContributionIntegral();
            case IntegralDetailConstants.INTEGRAL_TYPE_BALANCE:
                return userIntegral.getBalance();
            case IntegralDetailConstants.INTEGRAL_TYPE_CB_FUNDS:
                return userIntegral.getCbfunds();
        }
        return BigDecimal.ZERO;
    }

    /*
     * 创建积分明细表
     * uid：用户id
     * integralType：'积分类型：0：增值积分 ，1：绿色积分，2：贡献值， 3：余额 ， 4：cb基金',
     * changeType： 变化值类型 ： 0：增加， 1：减少
     * value：变化值
     * reason：原因（来源或去向）
     * remainder：积分变化后的剩余
     * */
    public UserIntegralDetail createIntegralDetail(Integer uid, String integralType, Integer changeType, BigDecimal value, String reason, BigDecimal remainder) {
        UserIntegralDetail userIntegralDetail = new UserIntegralDetail();
        userIntegralDetail.setUid(uid);
        userIntegralDetail.setIntegralType(integralType);
        userIntegralDetail.setChangeType(changeType);
        userIntegralDetail.setValue(value);
        userIntegralDetail.setReason(reason);
        userIntegralDetail.setRemainder(remainder);
        userIntegralDetail.setUpdateTime(DateUtil.nowDateTime());
        return userIntegralDetail;
    }

    /*
     * 存积分明细表
     * uid：用户id
     * integralType：'积分类型：0：增值积分 ，1：绿色积分，2：贡献值， 3：余额 ， 4：cb基金',
     * changeType： 变化值类型 ： 0：增加， 1：减少
     * value：变化值
     * reason：原因（来源或去向）
     * remainder：积分变化后的剩余
     * */
    public Boolean saveIntegralDetail(Integer uid, String integralType, Integer changeType, BigDecimal value, String reason, BigDecimal remainder) {
        UserIntegralDetail userIntegralDetail = new UserIntegralDetail();
        userIntegralDetail.setUid(uid);
        userIntegralDetail.setIntegralType(integralType);
        userIntegralDetail.setChangeType(changeType);
        userIntegralDetail.setValue(value);
        userIntegralDetail.setReason(reason);
        userIntegralDetail.setRemainder(remainder);
        userIntegralDetail.setUpdateTime(DateUtil.nowDateTime());
        boolean save = userIntegralDetailService.save(userIntegralDetail);
        if (!save){
            throw new CrmebException("保存用户积分明细失败！");
        }
        return save;
    }


    /*
     * 补贴逻辑
     * totalTurnover：总营业额/天
     * integralRemainder：个人增值积分剩余值
     * allIntegral：平台总增值积分*/
    public BigDecimal subsidyLogic(BigDecimal totalTurnover, BigDecimal integralRemainder, BigDecimal allIntegral) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        BigDecimal subsidy = integralParameter.getSubsidyParameter().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return totalTurnover.multiply(subsidy.multiply(integralRemainder).divide(allIntegral, 2, RoundingMode.HALF_UP));
    }

    //    /*
    //     * 根据贡献值计算增值积分变化值
    //     */
    //    public BigDecimal getValueAddByContribution(BigDecimal contributionChange, ) {
    //        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
    //        BigDecimal subsidy = integralParameter.getSubsidyParameter().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
    //        return totalTurnover.multiply(subsidy.multiply(integralRemainder).divide(allIntegral, 2, RoundingMode.HALF_UP));
    //    }


    /*
     * 增值积分转余额
     * principal：本金补贴
     * valueAdd：增值积分补贴
     */
    public BigDecimal valueAddTransInBalanceDaily(BigDecimal principal, BigDecimal valueAdd) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        return principal.add(valueAdd);
    }

    /*
     * 绿色积分的消费/互转所需的手续费
     * amount：消费或互转的金额
     * valueAdd：增值积分补贴
     */
    public BigDecimal premiumOfGreen(BigDecimal amount) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        // premium：手续费 参数
        BigDecimal premium = integralParameter.getPremium().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return amount.multiply(premium);
    }

    /*
     * 绿色积分的每天每天释放
     * release：释放比
     */
    public BigDecimal releaseOfGreen(BigDecimal nowGreenIntegral) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        BigDecimal release = integralParameter.getReleaseParameter().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return nowGreenIntegral.multiply(release);
    }

    //---------------------------分享加速----------------------------------------
    /*
     * 消费时产生的增值积分变化（只是变化值，不算当前积分值）*/
    public BigDecimal consumeTransInValueAdd(BigDecimal consumeSpent) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        BigDecimal multiple = integralParameter.getMultipleParameter().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return consumeSpent.multiply(multiple);
    }

    /*
     * 消费时产生的绿色积分变化（只是变化值，不算当前积分值）*/
    public BigDecimal consumeTransInGreen(BigDecimal consumeSpent) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        BigDecimal green = integralParameter.getGreenParameter().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return consumeSpent.multiply(green);
    }

    /*
     * 消费时产生的贡献值变化，分享人获得（只是变化值，不算当前积分值）*/
    public BigDecimal consumeTransInContributionByShare(BigDecimal consumeSpent,BigDecimal pv) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        // 被分享人首次消费
        BigDecimal firstShare = integralParameter.getFirstShare().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        // 动态折扣
        BigDecimal discount = pv.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return consumeSpent.multiply(firstShare).multiply(discount);
    }

    /*
     * 消费时产生的贡献值变化，每次消费都可获得（只是变化值，不算当前积分值）*/
    public BigDecimal consumeTransInContribution(BigDecimal consumeSpent) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        BigDecimal contribution = integralParameter.getContributionParameter().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return consumeSpent.multiply(contribution);
    }

    /*
     * 消费增值积分的折扣后
     * */
    public BigDecimal consumeValueAddAfterDiscount(BigDecimal consumeSpent,BigDecimal pv) {
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);
        // 动态折扣
        BigDecimal discount = pv.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return consumeSpent.multiply(discount);
    }

    /**
     * 增值积分转余额（消费, 推广时产生金额, 分享发起者 ）
     * @param nowValueAddIntegral 现在的增值积分
     * @param isFirstPush 收单
     * @param isCommonPush 复单
     * @return
     */
    public BigDecimal valueAddTransInBalanceByPush(BigDecimal nowValueAddIntegral, Boolean isFirstPush, Boolean isCommonPush,BigDecimal pv) {
        // TODO 如果想将参数改成动态的话改这里
        // 获取第一种积分参数模板
        IntegralParameter integralParameter = integralParameterService.getIntegralParameter(1);

        // 初始化值0
        BigDecimal push = BigDecimal.ZERO;
        if (isCommonPush) {
            // 获取复单的转换比率 10%
            push = integralParameter.getCommonPush().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
            if (isFirstPush) {
                //获取首单的转换比率 20%
                push = integralParameter.getFirstPush().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
            }
        }
        // 动态折扣
        BigDecimal discount = pv.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return nowValueAddIntegral.multiply(push).multiply(discount);
    }

    //    --------------------------------流量津贴加速-------------------------------


    /**
     * 团队的销售额的分红
     * @param level
     * @param storeOrder
     * @return
     */
    public BigDecimal saleDividend(Integer level,StoreOrder storeOrder) {
        // 获取商品的pv值
        BigDecimal pv = orderPayService.getPv(storeOrder);
        SystemUserLevel levelParameter = systemUserLevelService.getLevelParameter(level);
        BigDecimal saleDividend = levelParameter.getSaleDividend().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        // 动态折扣
        BigDecimal discount = pv.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return storeOrder.getPayPrice().multiply(saleDividend).divide(discount, 5, RoundingMode.HALF_UP);
    }

    /**
     * 小市场的分红
     * @param level
     * @param totalMoney
     * @return
     */
    public BigDecimal marketDividend(Integer level, BigDecimal totalMoney) {
        SystemUserLevel levelParameter = systemUserLevelService.getLevelParameter(level);
        BigDecimal marketDividend = levelParameter.getMarketDividend().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return totalMoney.multiply(marketDividend);
    }

    /**
     * 个人（领导者）的的分红
     * @param level
     * @param marketDividendMoney
     * @return
     */
    public BigDecimal personalDividend(Integer level, BigDecimal marketDividendMoney) {
        SystemUserLevel levelParameter = systemUserLevelService.getLevelParameter(level);
        BigDecimal personalDividend = levelParameter.getPersonalDividend().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return marketDividendMoney.multiply(personalDividend);
    }

    /**
     * 成员的的分红
     * @param level
     * @param marketDividendMoney
     * @param number
     * @return
     */
    public BigDecimal memberDividend(Integer level, BigDecimal marketDividendMoney, Integer number) {
        SystemUserLevel levelParameter = systemUserLevelService.getLevelParameter(level);
        BigDecimal memberDividend = levelParameter.getMemberDividend().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        return marketDividendMoney.multiply(memberDividend).divide(BigDecimal.valueOf(number), 2, RoundingMode.HALF_UP);
    }

    /**
     * 极差的分红
     * @param lowLevel
     * @param upLevel
     * @param payPrice
     * @return
     */
    public BigDecimal gradeDividend(Integer lowLevel, Integer upLevel, BigDecimal payPrice) {
        SystemUserLevel lowParameter = systemUserLevelService.getLevelParameter(lowLevel);
        SystemUserLevel upParameter = systemUserLevelService.getLevelParameter(upLevel);
        BigDecimal lowDividend = lowParameter.getSaleDividend().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        BigDecimal upDividend = upParameter.getSaleDividend().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        BigDecimal different = upDividend.subtract(lowDividend);
        return payPrice.multiply(different);
    }

    //    ----------------------合伙人---------------------

    /**
     * 合伙人每天的分润
     * @param level
     * @param dailySales
     * @return
     */
    public BigDecimal partnerDividendDaily(Integer level, BigDecimal dailySales) {
        SystemUserLevel systemUserLevel = systemUserLevelService.getLevelParameter(level);
        BigDecimal partnerDividend = systemUserLevel.getPersonalDividend().divide(BigDecimal.valueOf(100), 5, RoundingMode.HALF_UP);
        return dailySales.multiply(partnerDividend);
    }

    /**
     * 合伙人每季度的分红
     * @param level
     * @param seasonSales
     * @param partnerNumber
     * @return
     */
    public BigDecimal partnerDividendSeason(Integer level, BigDecimal seasonSales, Integer partnerNumber) {
        SystemUserLevel systemUserLevel = systemUserLevelService.getLevelParameter(level);
        // 将合伙人的市场分红参数设置为1%后当作季度销售的百分之几的参数
        BigDecimal partnerDividend = systemUserLevel.getMarketDividend().divide(BigDecimal.valueOf(100), 5, RoundingMode.HALF_UP);
        BigDecimal number = BigDecimal.valueOf(partnerNumber);
        return seasonSales.multiply(partnerDividend).divide(number, 2, RoundingMode.HALF_UP);
    }
}
